package org.fxcontainer.controller
{
	import mx.events.BrowserChangeEvent;
	import mx.managers.BrowserManager;
	import mx.managers.IBrowserManager;
	
	import org.as3commons.logging.ILogger;
	import org.as3commons.logging.LoggerFactory;
	import org.fxcontainer.actions.ControlAppearAction;
	import org.fxcontainer.actions.ControlInvocationAction;
	import org.fxcontainer.actions.ProcessNavigateAction;
	import org.fxcontainer.actions.URLChangeAction;
	import org.fxcontainer.commands.ProcessNavigateCommand;
	import org.fxcontainer.commands.navigation.chain.ControlURL;
	import org.fxcontainer.utils.URLProcessor;
	
	/**
	 * Main framework class that performs basic initializations.
	 * @author Izzet_Mustafayev
	 */
	public class ApplicationController 
	{
		
		/**
		 * The logger reference. 
		 */
		static private var logger:ILogger = LoggerFactory.getClassLogger(ApplicationController);
		 
		/**
		 * Creates application controller and registers required application artifacts.
		 */
		public function ApplicationController()
		{
			super();
			//register browser URL change event handler
			var browserManager:IBrowserManager = BrowserManager.getInstance(); 
			browserManager.addEventListener(BrowserChangeEvent.URL_CHANGE, handleURL);
			browserManager.init("/");
			//register basic actions
			this.registerActions();
		}
		
		/**
		 * Registers application actions handlers.
		 */
		private function registerActions():void
		{
			logger.debug("Registers framework actions.");
			//register navigate action handler
			CommandController.registerAction(new URLChangeAction());
			CommandController.registerAction(new ProcessNavigateAction());
			//register controll appearence action handler
			CommandController.registerAction(new ControlAppearAction());
			//register control invocation action handler
			CommandController.registerAction(new ControlInvocationAction());
		}
		
		/**
		 * Handles browser URL change event. 
		 * @param event the event to handle
		 */
		private function handleURL(event:BrowserChangeEvent):void
		{
			if (null  != event){
				var urlHelper:URLProcessor = new URLProcessor();
				//navigate to other page
				if (!urlHelper.isOnPage()){
					//resolve page to navigate to
					var pageName:String = urlHelper.resolvePage();
					var controls:Array = urlHelper.resolveControls();
					//controls invocation 
					if (null != controls && controls.length>0){
						for(var c:int=0; c<controls.length; c++){
							var control:ControlURL = ControlURL(controls[c]);
							processPageNavigateControl(pageName, control.control, control.method, control.arguments);
						}
					}
					//navigate to page
					if (null == controls || (null != controls && controls.length<=0)){
						processPageNavigate(pageName);
					}	
				}
			}
		}
		
		private function processPageNavigate(pageName:String):void
		{
			new ProcessNavigateCommand(ProcessNavigateCommand.PAGE_NAVIGATE_CMD, pageName).dispatch();
		}
		
		private function processPageNavigateControl(pageName:String, controlName:String, methodName:String=null, ... methodArgs:Array):void
		{
			var navigationCommand:ProcessNavigateCommand = new ProcessNavigateCommand(ProcessNavigateCommand.PAGE_CTRL_INVOKE_CMD, pageName, controlName);
			navigationCommand.methodName = methodName;
			navigationCommand.methodArgs = methodArgs;
			navigationCommand.dispatch();
		}
	}
}